package org.ceteca.explica.core.util;

import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.List;

import org.ceteca.explica.client.ClientContext;
import org.ceteca.explica.core.ExplicaException;
import org.ceteca.explica.core.InterfaceErrors;
import org.ceteca.explica.core.InterfaceExplica;
import org.ceteca.explica.core.common.BaseVO;
import org.ceteca.explica.core.common.CommonManager;
import org.ceteca.explica.core.common.CountryOT;
import org.ceteca.explica.core.common.StateOT;
import org.ceteca.explica.core.partners.InterfacePartnersErrors;
import org.eclipse.swt.widgets.Combo;

public class AddressUtils {
	private static AddressUtils instance;
	private ArrayList<CountryOT> countries = new ArrayList<CountryOT>();
	private ArrayList<StateOT> states = new ArrayList<StateOT>();
	
	public static AddressUtils getInstance() {
		if (instance == null){
			instance = new AddressUtils();
			
		}
		return instance;
	}
	
	
	
	
	public AddressUtils() {
		super();
		loadCountries();
		loadStates();
	}




	private void loadCountries() {
		countries.clear();

		OperationResult result = new OperationResult();
		List<BaseVO> list = null;
		CommonManager manager;
		try {
			manager = this.getRemote();
			list = manager.queryEntities(null, "", CountryOT.class);
			result.addResultMessage(OperationResult.RESULT_OK, ClientContext
					.getInstance().getMsgCatalog().newResultMessage(
							InterfacePartnersErrors.MSG_ENTITY_RETRIVE_OK));
		} catch (ExplicaException e) {
			result
					.addResultMessage(OperationResult.RESULT_ERROR, e
							.getResMsg());
			e.printStackTrace();
		} catch (RemoteException e) {
			result
					.addResultMessage(
							OperationResult.RESULT_ERROR,
							ClientContext
									.getInstance()
									.getMsgCatalog()
									.newResultMessage(
											InterfacePartnersErrors.ERR_RMI_METHOD_NOT_FOUND,
											e));
			e.printStackTrace();
		}
		if (list != null)
			for (BaseVO item : list)
				countries.add((CountryOT) item);

	}








	private void loadStates() {
		states.clear();

		OperationResult result = new OperationResult();
		List<BaseVO> list = null;
		CommonManager manager;
		try {
			manager = this.getRemote();
			list = manager.queryEntities(null, "", StateOT.class);
			result.addResultMessage(OperationResult.RESULT_OK, ClientContext
					.getInstance().getMsgCatalog().newResultMessage(
							InterfaceErrors.MSG_ENTITY_RETRIVE_OK));
		} catch (ExplicaException e) {
			result
					.addResultMessage(OperationResult.RESULT_ERROR, e
							.getResMsg());
			e.printStackTrace();
		} catch (RemoteException e) {
			result.addResultMessage(OperationResult.RESULT_ERROR, ClientContext
					.getInstance().getMsgCatalog().newResultMessage(
							InterfaceErrors.ERR_RMI_METHOD_NOT_FOUND, e));
			e.printStackTrace();
		}
		if (list != null)
			for (BaseVO item : list)
				states.add((StateOT) item);

	}

	
	private CommonManager getRemote() throws ExplicaException {

		try {

			Registry registry = LocateRegistry
					.getRegistry(InterfaceExplica.RMI_REGISTRY_PORT);

			CommonManager manager = (CommonManager) registry
					.lookup(InterfaceExplica.JNDI_COMMON_MANAGER_EXPORT_NAME);

			return manager;
		} catch (AccessException aEx) {
			aEx.printStackTrace();
			throw new ExplicaException(
					ClientContext
							.getInstance()
							.getMsgCatalog()
							.newResultMessage(
									InterfaceErrors.ERR_RMI_NO_ACCESS,
									aEx,
									(Object) InterfaceExplica.JNDI_COMMON_MANAGER_EXPORT_NAME,
									(Object) null));
		} catch (NotBoundException nEx) {
			nEx.printStackTrace();
			throw new ExplicaException(
					ClientContext
							.getInstance()
							.getMsgCatalog()
							.newResultMessage(
									InterfaceErrors.ERR_RMI_NOT_BOUND,
									nEx,
									(Object) InterfaceExplica.JNDI_COMMON_MANAGER_EXPORT_NAME,
									(Object) null));
		} catch (RemoteException rEx) {
			rEx.printStackTrace();
			throw new ExplicaException(
					ClientContext
							.getInstance()
							.getMsgCatalog()
							.newResultMessage(
									InterfaceErrors.ERR_RMI_METHOD_NOT_FOUND,
									rEx,
									(Object) InterfaceExplica.JNDI_COMMON_MANAGER_EXPORT_NAME,
									(Object) null));
		}
	}

	public ArrayList<CountryOT> getCountries() {
		return countries;
	}

	public void setCountries(ArrayList<CountryOT> countries) {
		this.countries = countries;
	}

	public ArrayList<StateOT> getStates() {
		return states;
	}

	public void setStates(ArrayList<StateOT> states) {
		this.states = states;
	}
	
	
	public int fillCountryCombo(Combo combobox, CountryOT selectedCountry){
		combobox.removeAll();
		int selected = -1;
		combobox.setData(getCountries());
		for (int i = 0; i < getCountries().size(); i++) {
			CountryOT f =getCountries().get(i);
			combobox.add(f.getName());
			if (selectedCountry != null)
				if (f.getIdCountry() == selectedCountry.getIdCountry()) {
					selected = i;
				}
		}
		if (selected > -1 && selectedCountry != null)
			combobox.select(selected);
		return selected;
	}
	
	
	
	
	public int fillStatesCombo(Combo combobox, CountryOT selectedCountry, StateOT selectedState){
		System.out.println("Seleccionando Pais:"+selectedCountry);
		System.out.println("Seleccionando State: "+selectedState);
		combobox.removeAll();
		int selected = -1;
		ArrayList<StateOT> myCountryStates=getStates(selectedCountry);
		combobox.setData(myCountryStates);
		for (int i = 0; i < myCountryStates.size(); i++) {
			
			StateOT f = myCountryStates.get(i);
			combobox.add(f.getName());
			if (selectedState != null)
				if (f.getIdState() == selectedState.getIdState()) {
					selected = i;
				}
		}
		if (selected > -1 && selectedState != null)
			combobox.select(selected);
		return selected;

	}
	
	public ArrayList<StateOT> getStates(CountryOT country){
		ArrayList<StateOT> result= new ArrayList<StateOT>();
		
		for (StateOT st:getStates()){
			if (country==null)
				result.add(st);
			else
			if (st.getCountry().getIdCountry()==country.getIdCountry())
				result.add(st);
		}
		return result;
	}
	
	
	public CountryOT getCountryFromCombo(Combo combobox){
		try {
		int selectedCountry = combobox.getSelectionIndex();
		ArrayList<CountryOT> c=(ArrayList<CountryOT>)combobox.getData();
		if (selectedCountry > -1)
			return c.get(selectedCountry);
		else
			return null;
		}catch (Exception e){
			return null;
		}
	}
	
	
	public StateOT getStateFromCombo(Combo combobox){
		try {
			int selected = combobox.getSelectionIndex();
			ArrayList<StateOT> s=(ArrayList<StateOT>)combobox.getData();
			if (selected > -1)
				return s.get(selected);
			else
				return null;
			}catch (Exception e){
				return null;
			}
	}
	
	
	public void refillComboStates(Combo comboStates, CountryOT newCountry){
		if (newCountry!=null){
			StateOT oldSelectedState=AddressUtils.getInstance().getStateFromCombo(comboStates);
			StateOT newSelectedState=null;
			if (oldSelectedState!=null )
				if (oldSelectedState.getCountry()!=null)
					if (oldSelectedState.getCountry().getIdCountry()==newCountry.getIdCountry())
						newSelectedState=oldSelectedState;
			AddressUtils.getInstance().fillStatesCombo(comboStates,
					newCountry, newSelectedState);
	
		}
	}
}
